/**
 * 
 */
package stc.skymobi.ebus.closure;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.Closure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import stc.skymobi.ebus.EventBus;


/**
 * @author hp
 *
 */
public class EventDispatchClosure implements Closure {

    private static final Logger logger = 
    	LoggerFactory.getLogger(EventDispatchClosure.class);
    
    private	EventBus	eventBus;
    
	private	Map<Class<?>, String> events = new HashMap<Class<?>, String>();
	
	private Closure	nulleventHandler = null;
	
	/**
	 * @return the nulleventHandler
	 */
	public Closure getNulleventHandler() {
		return nulleventHandler;
	}

	/**
	 * @param nulleventHandler the nulleventHandler to set
	 */
	public void setNulleventHandler(Closure nulleventHandler) {
		this.nulleventHandler = nulleventHandler;
	}

	public Collection<String> getTypeEvents() {
		Collection<String> ret = new ArrayList<String>();
		
        for (Map.Entry<Class<?>, String> entry : events.entrySet()) {
        	ret.add( entry.getKey().getSimpleName() + "<-->" + entry.getValue());
        }
        
        return	ret;
	}
	
	public Map<Class<?>, String> getEvents() {
        return Collections.unmodifiableMap(events);
	}

	public void setEvents(Map<Class<?>, String> events) {
        this.events.clear();
        
        for (Map.Entry<Class<?>, String> entry : events.entrySet()) {
            if ( null != entry.getValue() ) {
                this.events.put(entry.getKey(), entry.getValue());
            }
        }
	}


	/* (non-Javadoc)
	 * @see org.apache.commons.collections.Closure#execute(java.lang.Object)
	 */
	public void execute(Object input) {
		if ( null == input ) {
			return;
		}
		
		String event = events.get(input.getClass());
		if ( null == event ) {
			if ( null != nulleventHandler ) {
				nulleventHandler.execute(input);
			}
			else {
				logger.warn("can't found event for " + input + ", just ignore.");
			}
			return;
		}
		
		if ( logger.isDebugEnabled() ) {
			logger.debug("fire event [" + event + "] <--> " + input);
		}
		eventBus.fireEvent(event, input);
	}


	public EventBus getEventBus() {
		return eventBus;
	}


	public void setEventBus(EventBus eventBus) {
		this.eventBus = eventBus;
	}

}
